package com.eastedu.superise.handler.basic;

import cn.hutool.core.thread.ThreadUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eastedu.client.encrypt.FileDecryptClient;
import com.eastedu.client.encrypt.FileEncryptClient;
import com.eastedu.client.encrypt.FileHlsEncryptClient;
import com.eastedu.client.encrypt.model.FileEncryptRequest;
import com.eastedu.converter.BasicResourceFileConverter;
import com.eastedu.exception.ServiceException;
import com.eastedu.repository.basic.mapper.BasicResourceFileMapper;
import com.eastedu.repository.basic.po.BasicResourceFilePO;
import com.eastedu.repository.basic.po.BasicResourcePO;
import com.eastedu.superise.handler.AbstractHistoricalDataHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 处理历史mp4文件加密
 *
 * @author zhangzhishuai
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FileEncryptDataHandler extends AbstractHistoricalDataHandler<BasicResourcePO> {

    private final BasicResourceFileMapper basicResourceFileMapper;
    private final BasicResourceFileConverter basicResourceFileConverter;
    private final FileDecryptClient fileDecryptClient;
    private final FileHlsEncryptClient fileHlsEncryptClient;
    private final JdbcTemplate jdbcTemplate;
    private final FileEncryptClient fileEncryptClient;


    /**
     * 加密范围 幼儿园和其他
     * @return sql
     */
    @Override
    protected String getSql() {
        return "SELECT\n" +
                "\tr.* \n" +
                "FROM\n" +
                "\tt_basic_resource r\n" +
                "\tINNER JOIN t_basic_resource_file f on f.basic_resource_id = r.id\n" +
                "WHERE\n" +
                "\tr.study_section_code IN ( 'GZ', 'CZ', 'XX' ) \n" +
                "\tAND r.category IN ( 1, 7, 8, 9, 10, 30, 32 ) \n" +
                "\tAND r.create_time > 1577808000000 \n" +
                "\tAND r.encrypt_state IS NULL \n" +
                "\tAND r.source_app_code NOT IN ( 'U-learning-Course-Service' ) \n" +
                "\tand f.extension = 'mp4'\n" +
                "ORDER BY\n" +
                "\tr.id \n";

//        return "SELECT\n" +
//                "\tr.* \n" +
//                "FROM\n" +
//                "\tt_basic_resource r\n" +
//                "\tINNER JOIN t_basic_resource_file f on f.basic_resource_id = r.id\n" +
//                "WHERE\n" +
//                "\tr.study_section_code IN ('XQ') \n" +
//                "\tAND r.category IN ( 1, 7, 8, 9, 10, 30, 32 ) \n" +
//                "\tAND r.encrypt_state IS NULL \n" +
//                "\tAND r.source_app_code NOT IN ( 'U-learning-Course-Service' ) \n" +
//                "\tand f.extension = 'mp4'\n" +
//                "ORDER BY\n" +
//                "\tr.id \n" +
//                "\tLIMIT 100";

    }



    @Override
    public void callback(BasicResourcePO po) {
        if (Objects.nonNull(po.getEncryptState())) {
            return;
        }
        List<BasicResourceFilePO> basicResourceFilePoList = this.basicResourceFileMapper
                .selectList(Wrappers.lambdaQuery(BasicResourceFilePO.class)
                        .eq(BasicResourceFilePO::getBasicResourceId, po.getId()));
        List<Long> fileIds = basicResourceFilePoList.stream().filter(o -> "mp4".equalsIgnoreCase(o.getExtension()))
                .map(BasicResourceFilePO::getFileId).map(Long::valueOf).distinct().collect(Collectors.toList());
        log.info("文件ID" + fileIds);
        CompletableFuture.runAsync(() -> this.mp4HlsFileEncrypt(fileIds));
        ThreadUtil.sleep(20, TimeUnit.SECONDS);
    }

    private void mp4HlsFileEncrypt(List<Long> fileIds) {
        fileIds.forEach(this.fileHlsEncryptClient::retryMqFileEncrypt);
    }


    private List<Long> mp4FileEncrypt(String baseResourceId, List<Long> fileIds) {
        FileEncryptRequest fileEncryptRequest = basicResourceFileConverter.toFileEncryptRequest(baseResourceId, fileIds);
        try {
            return fileDecryptClient.createFileEncrypt(fileEncryptRequest);
        } catch (Exception e) {
            log.error("调用解密服务加密失败：", e);
            throw new ServiceException("调用解密服务加密失败：" + e.getMessage());
        }
    }

}
